package api

import (
	"github.com/gin-gonic/gin"
	"github.com/sirupsen/logrus"
	swaggerFiles "github.com/swaggo/files"
	ginSwagger "github.com/swaggo/gin-swagger"
	"github.com/yourusername/virt-manager-go/internal/api/handlers"
	"github.com/yourusername/virt-manager-go/internal/api/middleware"
	"github.com/yourusername/virt-manager-go/internal/service"
)

// NewRouter creates and configures the API router
func NewRouter(connMgr *service.ConnectionManager, serialProxy *service.SerialProxy, graphicsProxy *service.GraphicsProxy, log *logrus.Logger) *gin.Engine {
	router := gin.New()

	// Add middlewares
	router.Use(gin.Recovery())
	router.Use(middleware.LoggingMiddleware(log))
	router.Use(middleware.CORSMiddleware())

	// Initialize handlers
	connectionHandler := handlers.NewConnectionHandler(connMgr, log)
	domainHandler := handlers.NewDomainHandler(connMgr, log)
	networkHandler := handlers.NewNetworkHandler(connMgr, log)
	storageHandler := handlers.NewStorageHandler(connMgr, log)
	systemHandler := handlers.NewSystemHandler(connMgr, log)
	consoleHandler := handlers.NewConsoleHandler(serialProxy, graphicsProxy, log)

	// API version 1
	v1 := router.Group("/api/v1")
	{
		// Connection management endpoints
		v1.GET("/connections", connectionHandler.ListConnections)
		v1.POST("/connections", connectionHandler.CreateConnection)
		v1.POST("/connections/reconnect-all", connectionHandler.ReconnectAll)

		// Single connection operations
		v1.GET("/connection", connectionHandler.GetConnection)
		v1.DELETE("/connection", connectionHandler.DeleteConnection)
		v1.POST("/connection/close", connectionHandler.CloseConnection)
		v1.GET("/connection/info", connectionHandler.GetConnectionInfo)
		v1.GET("/connection/capabilities", connectionHandler.GetConnectionCapabilities)
		v1.POST("/connection/set-default", connectionHandler.SetDefaultConnection)
		v1.POST("/connection/reconnect", connectionHandler.ReconnectConnection)

		// System endpoints
		v1.GET("/connection/health", connectionHandler.HealthCheck)
		v1.GET("/system/info", systemHandler.GetSystemInfo)
		v1.GET("/system/capabilities", systemHandler.GetCapabilities)

		// Domain (VM) endpoints
		v1.GET("/domains", domainHandler.ListDomains)
		v1.POST("/domains", domainHandler.CreateDomain)
		v1.GET("/domain", domainHandler.GetDomain)
		v1.DELETE("/domain", domainHandler.DeleteDomain)
		v1.GET("/domain/xml", domainHandler.GetDomainXML)

		// Domain actions
		v1.POST("/domain/start", domainHandler.StartDomain)
		v1.POST("/domain/shutdown", domainHandler.ShutdownDomain)
		v1.POST("/domain/reboot", domainHandler.RebootDomain)
		v1.POST("/domain/force-stop", domainHandler.ForceStopDomain)
		v1.POST("/domain/suspend", domainHandler.SuspendDomain)
		v1.POST("/domain/resume", domainHandler.ResumeDomain)

		// Domain configuration
		v1.PUT("/domain/vcpus", domainHandler.SetVCPUs)
		v1.PUT("/domain/memory", domainHandler.SetMemory)

		// Domain statistics
		v1.GET("/domain/stats", domainHandler.GetDomainStats)
		v1.GET("/domain/status", domainHandler.GetDomainStatus)

		// Console endpoints
		v1.GET("/console/info", consoleHandler.GetConsoleInfos) // Default to serial
		v1.GET("/console/serial/info", consoleHandler.GetSerialConsoleInfo)
		v1.GET("/console/vnc/info", consoleHandler.GetVNCInfo)
		v1.GET("/console/spice/info", consoleHandler.GetSPICEInfo)

		// Console WebSocket connections
		v1.GET("/console/serial", consoleHandler.HandleSerialConsoleWebSocket)
		v1.GET("/console/vnc", consoleHandler.HandleVNCWebSocket)
		v1.GET("/console/spice", consoleHandler.HandleSPICEWebSocket)

		// Console session management
		v1.DELETE("/console/serial/sessions", consoleHandler.CloseVMSerialSessions)

		// Network endpoints
		v1.GET("/networks", networkHandler.ListNetworks)
		v1.POST("/networks", networkHandler.CreateNetwork)
		v1.GET("/network", networkHandler.GetNetwork)
		v1.DELETE("/network", networkHandler.DeleteNetwork)
		v1.POST("/network/start", networkHandler.StartNetwork)
		v1.POST("/network/stop", networkHandler.StopNetwork)

		// Storage endpoints
		v1.GET("/storage/pools", storageHandler.ListPools)
		v1.POST("/storage/pools", storageHandler.CreatePool)
		v1.GET("/storage/pool", storageHandler.GetPool)
		v1.DELETE("/storage/pool", storageHandler.DeletePool)
		v1.POST("/storage/pool/start", storageHandler.StartPool)
		v1.POST("/storage/pool/stop", storageHandler.StopPool)

		// Storage volumes
		v1.GET("/storage/volumes", storageHandler.ListVolumes)
		v1.POST("/storage/volumes", storageHandler.CreateVolume)
		v1.GET("/storage/volume", storageHandler.GetVolume)
		v1.DELETE("/storage/volume", storageHandler.DeleteVolume)

		// Template endpoints
		v1.POST("/templates/generate", domainHandler.GenerateFromTemplate)

		// Health check
		v1.GET("/health", func(c *gin.Context) {
			c.JSON(200, gin.H{
				"status": "healthy",
			})
		})
	}

	// Swagger documentation
	router.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))

	return router
}
